﻿using System;
using System.Collections.Generic;
using System.Text;

using ET;
using Marx;
using Server;
using Marx.Utils;

namespace Demo
{
    [ActorMessageHandler]
    public class SSCreatePlayerHandler : AMActorRpcHandler<Scene, SSCreatePlayerRequest, SSCreatePlayerResponse>
    {
        protected override async ETTask Run(Scene actor, SSCreatePlayerRequest request, SSCreatePlayerResponse response, Action reply)
        {
            using (await CoroutineLockComponent.Instance.Wait(MarxCoroutineLock.Player, request.PlayerId))
            {
                var manager = actor.GetComponent<PlayerManager>();
                var player = manager.GetChild<Player>(request.PlayerId);
                if (player == null)
                {
                    player = CreatePlayer(manager, request.Account, request.AccountId, request.PlayerId);
                    try
                    {
                        await player.LoadFromDB();
                        await player.AddLocation();

                        if (player.BaseInfo.FirstLogin)
                        {
                            await FirstLogin(player);
                        }
                        await player.Checkout();
                    }
                    catch (Exception e)
                    {
                        Log.Error(e);
                        player.Dispose();
                        response.Error = ResultCode.ERR_CreatePlayerFail;
                        response.Message = "创建玩家失败";
                        reply();
                        return;
                    }

                    player.AddComponent<MailBoxComponent>();
                    await player.AddLocation();
                }

                response.PlayerActor = player.InstanceId;
                player.SetAgentActor(request.AgentActor);
                SendAllPlayerInfo(player);
                reply();

                Log.Info("---------------Create Player Success--------------");
            }
        }

        private Player CreatePlayer(PlayerManager manager, string account, long accountId, long playerId)
        {
            var player = manager.AddChildWithId<Player, string, long>(playerId, account, accountId);

            //TODO:
            //Add All Components
            //player.AddComponent<PlayerAlertInfo>();
            //player.AddComponent<PlayerEventInfo>();
            //player.AddComponent<PlayerBagInfo>();
            //player.AddComponent<PlayerPropertyInfo>();
            //player.AddComponent<PlayerThingsRecordInfo>();
            //player.AddComponent<PlayerBattleInfo>();
            //player.AddComponent<PlayerBattleRecordInfo>();
            //player.AddComponent<PlayerMailInfo>();
            //player.AddComponent<PlayerFriendInfo>();
            //player.AddComponent<PlayerChatInfo>();
            //player.AddComponent<PlayerRedNoticeInfo>();
            //player.AddComponent<PlayerTeamInfo>();
            //player.AddComponent<PlayerOptionInfo>();
            //player.AddComponent<PlayerDaySignInfo>();
            //player.AddComponent<PlayerGuildInfo>();
            return player;
        }

        private async ETTask FirstLogin(Player player)
        {
            //player.GetComponent<PlayerBagInfo>().FirstLogin();
            //player.GetComponent<PlayerDaySignInfo>().FirstLogin();

            //player.BaseInfo.FirstLogin = false;
            await player.SaveBaseInfo();
        }

        private void SendAllPlayerInfo(Player player)
        {
            PlayerAllInfoProto proto = new PlayerAllInfoProto();
            //proto.Bag = player.GetComponent<PlayerBagInfo>().GetProto();
            //proto.Property = player.GetComponent<PlayerPropertyInfo>().GetProto();
            //proto.Battle = player.GetComponent<PlayerBattleInfo>().GetProto();
            //proto.BattleRecord = player.GetComponent<PlayerBattleRecordInfo>().GetProto();
            //proto.ThingsRecord = player.GetComponent<PlayerThingsRecordInfo>().GetProto();
            //proto.ChatMessage = player.GetComponent<PlayerChatInfo>().GetProto();
            //proto.RedNotices = player.GetComponent<PlayerRedNoticeInfo>().GetProto();
            //proto.Team = player.GetComponent<PlayerTeamInfo>().GetProto();
            //proto.InTeamMatch = player.GetComponent<PlayerTeamInfo>().InTeamMatch;


            EnterGameAllInfoNotify ntf = new EnterGameAllInfoNotify()
            {
                PlayerAllInfo = proto,
                TimezoneOffset = (int)TimeZoneInfo.Local.BaseUtcOffset.TotalMilliseconds,
                UtcTimestamp = TimeUtils.CurUnixTimestamp,
                ServerId = 1,
                PlayerId = player.Id,
            };
            player.SendMessageToClient(ntf);
        }

    }


    [ActorMessageHandler]
    public class SSDestroyPlayerHandler : AMActorRpcHandler<Player, SSDestroyPlayerRequest, SSDestroyPlayerResponse>
    {
        protected override async ETTask Run(Player unit, SSDestroyPlayerRequest request, SSDestroyPlayerResponse response, Action reply)
        {
            await unit.Destroy();
            reply();
        }
    }
}
